unit ec_condbranch;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, Buttons,
  ComCtrls, StdCtrls, EditBtn, Spin, ec_base, Types, fpjson;

type

  { TECCondBranchFrame }

  TECCondBranchFrame = class(TECBaseFrame)
    ActorArmourComboBox: TComboBox;
    ActorStateComboBox: TComboBox;
    ActorArmourRadioButton: TRadioButton;
    ActorClassComboBox: TComboBox;
    ActorClassRadioButton: TRadioButton;
    ActorInPartyRadioButton: TRadioButton;
    ActorNameEdit: TEdit;
    ActorNameRadioButton: TRadioButton;
    ActorSkillComboBox: TComboBox;
    ActorSkillRadioButton: TRadioButton;
    ActorStateRadioButton: TRadioButton;
    ActorWeaponComboBox: TComboBox;
    ActorWeaponRadioButton: TRadioButton;
    ArmourComboBox: TComboBox;
    CodeEdit: TEdit;
    DummyPage4RadioButton: TRadioButton;
    EnemyAppearedInBattleRadioButton: TRadioButton;
    EnemyStateComboBox: TComboBox;
    EnemyStateRadioButton: TRadioButton;
    KeyComboBox: TComboBox;
    KeyRadioButton: TRadioButton;
    CodeRadioButton: TRadioButton;
    ActorCheckPanel: TPanel;
    EnemyCheckPanel: TPanel;
    WeaponIncludeEquipmentCheckBox: TCheckBox;
    DummyPage3RadioButton: TRadioButton;
    DummyPage2RadioButton: TRadioButton;
    ItemComboBox: TComboBox;
    GoldOperatorComboBox: TComboBox;
    GoldRadioButton: TRadioButton;
    WeaponComboBox: TComboBox;
    ItemRadioButton: TRadioButton;
    GoldSpinEdit: TSpinEdit;
    ArmourIncludeEquipmentCheckBox: TCheckBox;
    WeaponRadioButton: TRadioButton;
    VehicleComboBox: TComboBox;
    MapObjectDirComboBox: TComboBox;
    MapObjectComboBox: TComboBox;
    EnemyComboBox: TComboBox;
    EnemyRadioButton: TRadioButton;
    ActorComboBox: TComboBox;
    ActorRadioButton: TRadioButton;
    MapObjectRadioButton: TRadioButton;
    VehicleRadioButton: TRadioButton;
    TimerMinutesLabel: TLabel;
    TimerSecondsLabel: TLabel;
    TimerMinutesSpinEdit: TSpinEdit;
    TimerSecondsSpinEdit: TSpinEdit;
    TimerRadioButton: TRadioButton;
    SelfSwitchComboBox: TComboBox;
    SelfSwitchRadioButton: TRadioButton;
    SelfSwitchStateComboBox: TComboBox;
    TimerOperationComboBox: TComboBox;
    VarVarOperandEditButton: TEditButton;
    VarVarOperandRadioButton: TRadioButton;
    VarConstOperandSpinEdit: TSpinEdit;
    VarConstOperandRadioButton: TRadioButton;
    VarOperandPanel: TPanel;
    VarEditButton: TEditButton;
    VarRadioButton: TRadioButton;
    SwitchStateComboBox: TComboBox;
    SwitchEditButton: TEditButton;
    ElseCheckBox: TCheckBox;
    CondPageControl: TPageControl;
    Page1TabSheet: TTabSheet;
    Page2TabSheet: TTabSheet;
    Page3TabSheet: TTabSheet;
    Page4TabSheet: TTabSheet;
    DummyPage1RadioButton: TRadioButton;
    SwitchRadioButton: TRadioButton;
    VarOperatorComboBox: TComboBox;
    ArmourRadioButton: TRadioButton;
    procedure ActorArmourRadioButtonChange(Sender: TObject);
    procedure ActorClassRadioButtonChange(Sender: TObject);
    procedure ActorNameRadioButtonChange(Sender: TObject);
    procedure ActorRadioButtonChange(Sender: TObject);
    procedure ActorSkillRadioButtonChange(Sender: TObject);
    procedure ActorStateRadioButtonChange(Sender: TObject);
    procedure ActorWeaponRadioButtonChange(Sender: TObject);
    procedure ArmourRadioButtonChange(Sender: TObject);
    procedure CodeRadioButtonChange(Sender: TObject);
    procedure EnemyRadioButtonChange(Sender: TObject);
    procedure EnemyStateRadioButtonChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure GoldRadioButtonChange(Sender: TObject);
    procedure ItemRadioButtonChange(Sender: TObject);
    procedure KeyRadioButtonChange(Sender: TObject);
    procedure MapObjectRadioButtonChange(Sender: TObject);
    procedure SelfSwitchRadioButtonChange(Sender: TObject);
    procedure SwitchEditButtonButtonClick(Sender: TObject);
    procedure SwitchEditButtonKeyPress(Sender: TObject; var Key: char);
    procedure SwitchRadioButtonChange(Sender: TObject);
    procedure TimerRadioButtonChange(Sender: TObject);
    procedure VarConstOperandRadioButtonChange(Sender: TObject);
    procedure VarEditButtonButtonClick(Sender: TObject);
    procedure VarRadioButtonChange(Sender: TObject);
    procedure VarVarOperandEditButtonButtonClick(Sender: TObject);
    procedure VarVarOperandRadioButtonChange(Sender: TObject);
    procedure VehicleRadioButtonChange(Sender: TObject);
    procedure WeaponRadioButtonChange(Sender: TObject);
  private
    SwitchId, VarId, VarVarOperandId: Integer;
    procedure RepositionDummyRadioButtons;
    procedure UnsetOptionsOnOtherPages(PageToKeep: Integer);
    procedure UpdateEditButtons;
    procedure InitialSetUp;
    function MakeCondition: TJSONArray;
  public
    procedure InitNew; override;
    procedure InitExisting; override;
    procedure MakeResultingCommand; override;
    function FindStartOfSubcommands(Index: Integer): Integer; override;
  end;

var
  ECCondBranchFrame: TECCondBranchFrame;

const
  KeyCodes: array [0..8] of String = (
    'ok', 'cancel', 'shift',
    'down', 'left', 'right', 'up',
    'pageup', 'pagedown'
  );

implementation

{$R *.lfm}

uses
  namedindexselection, globals, constants, comboboxhelper, namehelper;


{ TECCondBranchFrame }

procedure TECCondBranchFrame.FormCreate(Sender: TObject);
begin
  RepositionDummyRadioButtons;
  UnsetOptionsOnOtherPages(-1);
end;

procedure TECCondBranchFrame.GoldRadioButtonChange(Sender: TObject);
begin
  if GoldRadioButton.Checked then
   UnsetOptionsOnOtherPages(4);
  GoldOperatorComboBox.Enabled := GoldRadioButton.Checked;
  GoldSpinEdit.Enabled := GoldRadioButton.Checked
end;

procedure TECCondBranchFrame.ItemRadioButtonChange(Sender: TObject);
begin
  if ItemRadioButton.Checked then
     UnsetOptionsOnOtherPages(4);
  ItemComboBox.Enabled := ItemRadioButton.Checked
end;

procedure TECCondBranchFrame.KeyRadioButtonChange(Sender: TObject);
begin
  if KeyRadioButton.Checked then
     UnsetOptionsOnOtherPages(4);
  KeyComboBox.Enabled := KeyRadioButton.Checked;
end;

procedure TECCondBranchFrame.MapObjectRadioButtonChange(Sender: TObject);
begin
  if MapObjectRadioButton.Checked then
     UnsetOptionsOnOtherPages(3);
  MapObjectComboBox.Enabled := MapObjectRadioButton.Checked;
  MapObjectDirComboBox.Enabled := MapObjectRadioButton.Checked
end;

procedure TECCondBranchFrame.ActorRadioButtonChange(Sender: TObject);
begin
  if ActorRadioButton.Checked then
     UnsetOptionsOnOtherPages(2);

  ActorInPartyRadioButton.Enabled := ActorRadioButton.Checked;

  ActorNameRadioButton.Enabled := ActorRadioButton.Checked;
  ActorNameEdit.Enabled := ActorNameRadioButton.Checked;

  ActorClassRadioButton.Enabled := ActorRadioButton.Checked;
  ActorClassComboBox.Enabled := ActorClassRadioButton.Checked;

  ActorSkillRadioButton.Enabled := ActorRadioButton.Checked;
  ActorSkillComboBox.Enabled := ActorSkillRadioButton.Checked;

  ActorWeaponRadioButton.Enabled := ActorRadioButton.Checked;
  ActorWeaponComboBox.Enabled := ActorWeaponRadioButton.Checked;

  ActorArmourRadioButton.Enabled := ActorRadioButton.Checked;
  ActorArmourComboBox.Enabled := ActorArmourRadioButton.Checked;

  ActorStateRadioButton.Enabled := ActorRadioButton.Checked;
  ActorStateComboBox.Enabled := ActorStateRadioButton.Checked;
end;

procedure TECCondBranchFrame.ActorSkillRadioButtonChange(Sender: TObject);
begin
  ActorSkillComboBox.Enabled := ActorSkillRadioButton.Checked;
end;

procedure TECCondBranchFrame.ActorStateRadioButtonChange(Sender: TObject);
begin
  ActorStateComboBox.Enabled := ActorStateRadioButton.Checked;
end;

procedure TECCondBranchFrame.ActorWeaponRadioButtonChange(Sender: TObject);
begin
  ActorWeaponComboBox.Enabled := ActorWeaponRadioButton.Checked;
end;

procedure TECCondBranchFrame.ArmourRadioButtonChange(Sender: TObject);
begin
  if ArmourRadioButton.Checked then
     UnsetOptionsOnOtherPages(4);
  ArmourComboBox.Enabled := ArmourRadioButton.Checked;
  ArmourIncludeEquipmentCheckBox.Enabled := ArmourRadioButton.Checked;
end;

procedure TECCondBranchFrame.CodeRadioButtonChange(Sender: TObject);
begin
  if CodeRadioButton.Checked then
     UnsetOptionsOnOtherPages(4);
  CodeEdit.Enabled := CodeRadioButton.Checked
end;

procedure TECCondBranchFrame.EnemyRadioButtonChange(Sender: TObject);
begin
  if EnemyRadioButton.Checked then
     UnsetOptionsOnOtherPages(3);

  EnemyComboBox.Enabled := EnemyRadioButton.Checked;
  EnemyAppearedInBattleRadioButton.Enabled := EnemyRadioButton.Checked;
  EnemyStateRadioButton.Enabled := EnemyRadioButton.Checked;
  EnemyStateComboBox.Enabled := EnemyStateRadioButton.Checked
end;

procedure TECCondBranchFrame.EnemyStateRadioButtonChange(Sender: TObject);
begin
  EnemyStateComboBox.Enabled := EnemyStateRadioButton.Checked
end;

procedure TECCondBranchFrame.ActorNameRadioButtonChange(Sender: TObject);
begin
  ActorNameEdit.Enabled := ActorNameRadioButton.Checked;
end;

procedure TECCondBranchFrame.ActorClassRadioButtonChange(Sender: TObject);
begin
  ActorClassComboBox.Enabled := ActorClassRadioButton.Checked;
end;

procedure TECCondBranchFrame.ActorArmourRadioButtonChange(Sender: TObject);
begin
  ActorArmourComboBox.Enabled := ActorArmourRadioButton.Checked;
end;

procedure TECCondBranchFrame.SelfSwitchRadioButtonChange(Sender: TObject);
begin
  if SelfSwitchRadioButton.Checked then
     UnsetOptionsOnOtherPages(1);
  SelfSwitchComboBox.Enabled := SelfSwitchRadioButton.Checked;
  SelfSwitchStateComboBox.Enabled := SelfSwitchRadioButton.Checked;
end;

procedure TECCondBranchFrame.SwitchEditButtonButtonClick(Sender: TObject);
begin
  SwitchId := NamedIndexSelectionForm.SelectSwitch(SwitchId, Game.Db);
  UpdateEditButtons
end;

procedure TECCondBranchFrame.SwitchEditButtonKeyPress(Sender: TObject;
  var Key: char);
begin
  Key := #0;
  if (Sender is TEditButton)
                and ((Sender as TEditButton).OnButtonClick <> nil) then
     (Sender as TEditButton).OnButtonClick(Sender);
end;

procedure TECCondBranchFrame.SwitchRadioButtonChange(Sender: TObject);
begin
  if SwitchRadioButton.Checked then
     UnsetOptionsOnOtherPages(1);
  SwitchEditButton.Enabled := SwitchRadioButton.Checked;
  SwitchStateComboBox.Enabled := SwitchRadioButton.Checked;
end;

procedure TECCondBranchFrame.TimerRadioButtonChange(Sender: TObject);
begin
  if TimerRadioButton.Checked then
     UnsetOptionsOnOtherPages(1);
  TimerOperationComboBox.Enabled := TimerRadioButton.Checked;
  TimerMinutesSpinEdit.Enabled := TimerRadioButton.Checked;
  TimerSecondsSpinEdit.Enabled := TimerRadioButton.Checked
end;

procedure TECCondBranchFrame.VarConstOperandRadioButtonChange(Sender: TObject);
begin
  VarConstOperandSpinEdit.Enabled := VarConstOperandRadioButton.Checked;
end;

procedure TECCondBranchFrame.VarEditButtonButtonClick(Sender: TObject);
begin
  VarId := NamedIndexSelectionForm.SelectVariable(VarId, Game.Db);
  UpdateEditButtons
end;

procedure TECCondBranchFrame.VarRadioButtonChange(Sender: TObject);
begin
  if VarRadioButton.Checked then
     UnsetOptionsOnOtherPages(1);
  VarEditButton.Enabled := VarRadioButton.Checked;
  VarOperatorComboBox.Enabled := VarRadioButton.Checked;

  VarConstOperandRadioButton.Enabled := VarRadioButton.Checked;
  VarConstOperandSpinEdit.Enabled := VarConstOperandRadioButton.Checked;

  VarVarOperandRadioButton.Enabled := VarRadioButton.Checked;
  VarVarOperandEditButton.Enabled := VarVarOperandRadioButton.Checked;

  UpdateEditButtons;
end;

procedure TECCondBranchFrame.VarVarOperandEditButtonButtonClick(Sender: TObject
  );
begin
  VarVarOperandId := NamedIndexSelectionForm.SelectVariable(VarVarOperandId,
                                                            Game.Db);
  UpdateEditButtons
end;

procedure TECCondBranchFrame.VarVarOperandRadioButtonChange(Sender: TObject);
begin
  VarVarOperandEditButton.Enabled := VarVarOperandRadioButton.Checked;
end;

procedure TECCondBranchFrame.VehicleRadioButtonChange(Sender: TObject);
begin
  if VehicleRadioButton.Checked then
     UnsetOptionsOnOtherPages(3);
  VehicleComboBox.Enabled := VehicleRadioButton.Checked
end;

procedure TECCondBranchFrame.WeaponRadioButtonChange(Sender: TObject);
begin
  if WeaponRadioButton.Checked then
     UnsetOptionsOnOtherPages(4);
  WeaponComboBox.Enabled := WeaponRadioButton.Checked;
  WeaponIncludeEquipmentCheckBox.Enabled := WeaponRadioButton.Checked;
end;

procedure TECCondBranchFrame.RepositionDummyRadioButtons;
begin
  (* It would be nice if we found a way to do without this, but I haven't found
     a better way to unselect all the radio buttons on a page. *)
  DummyPage1RadioButton.Left := -100;
  DummyPage2RadioButton.Left := -100;
  DummyPage3RadioButton.Left := -100;
  DummyPage4RadioButton.Left := -100;
end;

procedure TECCondBranchFrame.UnsetOptionsOnOtherPages(PageToKeep: Integer);
begin
  if PageToKeep <> 1 then
     DummyPage1RadioButton.Checked := true;
  if PageToKeep <> 2 then
     DummyPage2RadioButton.Checked := true;
  if PageToKeep <> 3 then
     DummyPage3RadioButton.Checked := true;
  if PageToKeep <> 4 then
     DummyPage4RadioButton.Checked := true;
end;

procedure TECCondBranchFrame.UpdateEditButtons;
begin
  SwitchEditButton.Text := Game.Db.GetSwitchName(SwitchId);
  VarEditButton.Text := Game.Db.GetVariableName(VarId);
  VarVarOperandEditButton.Text := Game.Db.GetVariableName(VarVarOperandId);
end;

procedure TECCondBranchFrame.InitialSetUp;
  procedure SetSwitchOptions(Box: TComboBox);
  begin
    with Box.Items do begin
      BeginUpdate;
      Clear;
      Add(rsConditionalBranch_isOn);
      Add(rsConditionalBranch_isOff);
      EndUpdate
    end;
    Box.ItemIndex := 0;
  end;

  procedure SetVariableOperations;
  begin
    with VarOperatorComboBox.Items do begin
      BeginUpdate;
      Clear;
      Add(rsEquals);
      Add(rsGreaterOrEqualThan);
      Add(rsLessOrEqualThan);
      Add(rsGreaterThan);
      Add(rsLessThan);
      Add(rsNotEqual);
      EndUpdate
    end;
    VarOperatorComboBox.ItemIndex := 0
  end;

  procedure SetTimerOptions;
  begin
    with TimerOperationComboBox.Items do begin
      BeginUpdate;
      Clear;
      Add(rsGreaterOrEqualThan);
      Add(rsLessOrEqualThan);
      EndUpdate
    end;
    TimerOperationComboBox.ItemIndex := 0;
  end;

  procedure FillEnemyList;
  var
    I: Integer;
    EnemyId: Integer;
    S: String;
  begin
    with EnemyComboBox.Items do begin
      BeginUpdate;
      Clear;
      for I := 0 to 7 do begin
        if (Troop <> nil) and (I < Troop.Arrays['members'].Count) then begin
          EnemyId := Troop.Arrays['members'].Objects[I].Integers['enemyId'];
          S := rsEnemyNumberName.Format([I+1, Db.Enemies.Objects[EnemyId].Strings['name']]);
        end else
          S := rsEnemyNumber.Format([I+1]);

        Add(S);
      end;
      EndUpdate;
    end;
    EnemyComboBox.ItemIndex := 0
  end;

  procedure FillMapObjectDirectionList;
  begin
    with MapObjectDirComboBox.Items do begin
      BeginUpdate;
      Clear;

      Add(rsConditionalBranch_charDownComboBox);
      Add(rsConditionalBranch_charLeftComboBox);
      Add(rsConditionalBranch_charRightComboBox);
      Add(rsConditionalBranch_charUpComboBox);

      EndUpdate;
    end;
    MapObjectDirComboBox.ItemIndex := 0
  end;

  procedure FillVehicleList;
  begin
    with VehicleComboBox.Items do begin
      BeginUpdate;
      Clear;

      Add(rsVehicleBoatComboBox);
      Add(rsVehicleShipComboBox);
      Add(rsVehicleAirshipComboBox);

      EndUpdate;
    end;
    VehicleComboBox.ItemIndex := 0;
  end;

  procedure SetGoldOperations;
  begin
    with GoldOperatorComboBox.Items do begin
      BeginUpdate;
      Clear;
      Add(rsGreaterOrEqualThan);
      Add(rsLessOrEqualThan);
      Add(rsLessThan);
      EndUpdate
    end;
    GoldOperatorComboBox.ItemIndex := 0
  end;

  procedure SetKeys;
  var
    I: Integer;
  begin
    with KeyComboBox.Items do begin
      BeginUpdate;
      Clear;

      for I := Low(KeyCodes) to High(KeyCodes) do
        Add(GetButtonName(KeyCodes[I]));
      EndUpdate
    end;
    KeyComboBox.ItemIndex := 0
  end;

begin
  SetSwitchOptions(SwitchStateComboBox);
  SetVariableOperations;
  SetSwitchOptions(SelfSwitchStateComboBox);
  FillUserSelfSwitchNameCombobox(SelfSwitchComboBox);
  SelfSwitchComboBox.ItemIndex := 0;
  SetTimerOptions;

  FillDbArrayComboBox(ActorComboBox, Game.Db.Actors);
  FillDbArrayComboBox(ActorClassComboBox, Game.Db.Classes);
  FillDbArrayComboBox(ActorSkillComboBox, Game.Db.Skills);
  FillDbArrayComboBox(ActorWeaponComboBox, Game.Db.Weapons);
  FillDbArrayComboBox(ActorArmourComboBox, Game.Db.Armours);
  FillDbArrayComboBox(ActorStateComboBox, Game.Db.States);

  FillEnemyList;
  FillDbArrayComboBox(EnemyStateComboBox, Game.Db.States);

  FillMapCharacterComboBox(MapObjectComboBox, Game.Map);
  MapObjectComboBox.ItemIndex := 0;
  FillMapObjectDirectionList;
  FillVehicleList;

  SetGoldOperations;
  FillDbArrayComboBox(ItemComboBox, Game.Db.Items);
  FillDbArrayComboBox(WeaponComboBox, Game.Db.Weapons);
  FillDbArrayComboBox(ArmourComboBox, Game.Db.Armours);
  SetKeys;

  SwitchId := 1;
  VarId := 1;
  VarVarOperandId := 1;
end;

function TECCondBranchFrame.MakeCondition: TJSONArray;
  function MakeVarCondition: TJSONArray;
  var
    OpType, Operand: Integer;
  begin
    if VarConstOperandRadioButton.Checked then begin
      OpType := 0;
      Operand := VarConstOperandSpinEdit.Value
    end else begin
      OpType := 1;
      Operand := VarVarOperandId
    end;

    MakeVarCondition := TJSONArray.Create([
      1, VarId, OpType, Operand, VarOperatorComboBox.ItemIndex
    ]);
  end;

  function MakeTimerCondition: TJSONArray;
  begin
    MakeTimerCondition := TJSONArray.Create([
      3,
      TimerMinutesSpinEdit.Value * 60 + TimerSecondsSpinEdit.Value,
      TimerOperationComboBox.ItemIndex
    ]);
  end;

  function MakeActorCondition: TJSONArray;
    procedure AddWithItemIndex(CheckType: Integer; List: TComboBox);
    begin
      Result.Add(CheckType);
      Result.Add(List.ItemIndex + 1);
    end;

  begin
    Result := TJSONArray.Create([
      4,
      ActorComboBox.ItemIndex + 1
    ]);

    if ActorInPartyRadioButton.Checked then
       Result.Add(0)
    else if ActorNameRadioButton.Checked then begin
      Result.Add(1);
      Result.Add(ActorNameEdit.Text);
    end else if ActorClassRadioButton.Checked then
      AddWithItemIndex(2, ActorClassComboBox)
    else if ActorSkillRadioButton.Checked then
      AddWithItemIndex(3, ActorSkillComboBox)
    else if ActorWeaponRadioButton.Checked then
      AddWithItemIndex(4, ActorWeaponComboBox)
    else if ActorArmourRadioButton.Checked then
      AddWithItemIndex(5, ActorArmourComboBox)
    else if ActorStateRadioButton.Checked then
      AddWithItemIndex(6, ActorStateComboBox);
  end;

  function MakeEnemyCondition: TJSONArray;
  begin
    Result := TJSONArray.Create([5, EnemyComboBox.ItemIndex]);
    if EnemyAppearedInBattleRadioButton.Checked then
       Result.Add(0)
    else begin
      Result.Add(1);
      Result.Add(EnemyStateComboBox.ItemIndex + 1);
    end;
  end;

begin
  if SwitchRadioButton.Checked then
     MakeCondition := TJSONArray.Create([
       0, SwitchId, SwitchStateComboBox.ItemIndex
     ])
  else if VarRadioButton.Checked then
     MakeCondition := MakeVarCondition
  else if SelfSwitchRadioButton.Checked then
     MakeCondition := TJSONArray.Create([
       2,
       Chr(Ord('A') + SelfSwitchComboBox.ItemIndex),
       SelfSwitchStateComboBox.ItemIndex
     ])
  else if TimerRadioButton.Checked then
     MakeCondition := MakeTimerCondition
  else if ActorRadioButton.Checked then
     MakeCondition := MakeActorCondition
  else if EnemyRadioButton.Checked then
     MakeCondition := MakeEnemyCondition
  else if MapObjectRadioButton.Checked then
     MakeCondition := TJSONArray.Create([
      6,
      MapObjectComboBox.ItemIndex - 1,
      (MapObjectDirComboBox.ItemIndex + 1) * 2
    ])
  else if VehicleRadioButton.Checked then
     MakeCondition := TJSONArray.Create([13, VehicleComboBox.ItemIndex])
  else if GoldRadioButton.Checked then
    MakeCondition := TJSONArray.Create([
      7, GoldSpinEdit.Value, GoldOperatorComboBox.ItemIndex
    ])
  else if ItemRadioButton.Checked then
    MakeCondition := TJSONArray.Create([8, ItemComboBox.ItemIndex + 1])
  else if WeaponRadioButton.Checked then
    MakeCondition := TJSONArray.Create([
      9, WeaponComboBox.ItemIndex + 1, WeaponIncludeEquipmentCheckBox.Checked
    ])
  else if ArmourRadioButton.Checked then
    MakeCondition := TJSONArray.Create([
      10, ArmourComboBox.ItemIndex + 1, ArmourIncludeEquipmentCheckBox.Checked
    ])
  else if KeyRadioButton.Checked then
    MakeCondition := TJSONArray.Create([
      11, KeyCodes[KeyComboBox.ItemIndex]
    ])
  else if CodeRadioButton.Checked then
    MakeCondition := TJSONArray.Create([
      12, CodeEdit.Text
    ])
end;

procedure TECCondBranchFrame.InitNew;
begin
  InitialSetUp;
  VarConstOperandRadioButton.Checked := True;

  UpdateEditButtons;
end;

procedure TECCondBranchFrame.InitExisting;
var
  Params: TJSONArray;

  procedure InitSwitchCondition;
  begin
    CondPageControl.PageIndex := 0;
    SwitchRadioButton.Checked := True;
    SwitchId := Params.Integers[1];
    SwitchStateComboBox.ItemIndex := Params.Integers[2];
    UpdateEditButtons
  end;

  procedure InitVariableCondition;
  begin
    CondPageControl.PageIndex := 0;
    VarRadioButton.Checked := True;
    VarId := Params.Integers[1];

    if Params.Integers[2] = 0 then begin
      VarConstOperandRadioButton.Checked := True;
      VarConstOperandSpinEdit.Value := Params.Integers[3]
    end else begin
      VarVarOperandRadioButton.Checked := True;
      VarVarOperandId := Params.Integers[3]
    end;

    VarOperatorComboBox.ItemIndex := Params.Integers[4];
    UpdateEditButtons
  end;

  procedure InitSelfSwitchCondition;
  begin
    CondPageControl.PageIndex := 0;
    SelfSwitchRadioButton.Checked := True;
    SelfSwitchComboBox.ItemIndex := Ord(Params.Strings[1][1]) - Ord('A');
    SelfSwitchStateComboBox.ItemIndex := Params.Integers[2];
  end;

  procedure InitTimerCondition;
  begin
    CondPageControl.PageIndex := 0;
    TimerRadioButton.Checked := True;
    TimerMinutesSpinEdit.Value := Params.Integers[1] div 60;
    TimerSecondsSpinEdit.Value := Params.Integers[1] mod 60;
    TimerOperationComboBox.ItemIndex := Params.Integers[2];
  end;

  procedure InitActorCondition;
    procedure SetWithItemIndex(RadioButton: TRadioButton; List: TComboBox);
    begin
      RadioButton.Checked := True;
      List.ItemIndex := Params.Integers[3] - 1;
    end;

  begin
    CondPageControl.PageIndex := 1;
    ActorRadioButton.Checked := True;
    ActorComboBox.ItemIndex := Params.Integers[1] - 1;
    case Params.Integers[2] of
      0: ActorInPartyRadioButton.Checked := True;
      1: begin
          ActorNameRadioButton.Checked := True;
          ActorNameEdit.Text := Params.Strings[3];
      end;
      2: SetWithItemIndex(ActorClassRadioButton, ActorClassComboBox);
      3: SetWithItemIndex(ActorSkillRadioButton, ActorSkillComboBox);
      4: SetWithItemIndex(ActorWeaponRadioButton, ActorWeaponComboBox);
      5: SetWithItemIndex(ActorArmourRadioButton, ActorArmourComboBox);
      6: SetWithItemIndex(ActorStateRadioButton, ActorStateComboBox);
    end;
  end;

  procedure InitEnemyCondition;
  begin
    CondPageControl.PageIndex := 2;
    EnemyRadioButton.Checked := True;
    EnemyComboBox.ItemIndex := Params.Integers[1];

    case Params.Integers[2] of
      0: EnemyAppearedInBattleRadioButton.Checked := True;
      1: begin
        EnemyStateRadioButton.Checked := True;
        EnemyStateComboBox.ItemIndex := Params.Integers[3] - 1;
      end;
    end;
  end;

  procedure InitMapObjectCondition;
  begin
    CondPageControl.PageIndex := 2;
    MapObjectRadioButton.Checked := True;
    MapObjectComboBox.ItemIndex := Params.Integers[1] + 1;
    MapObjectDirComboBox.ItemIndex := Params.Integers[2] div 2 - 1;
  end;

  procedure InitVehicleCondition;
  begin
    CondPageControl.PageIndex := 2;
    VehicleRadioButton.Checked := True;
    VehicleComboBox.ItemIndex := Params.Integers[1];
  end;

  procedure InitGoldCondition;
  begin
    CondPageControl.PageIndex := 3;
    GoldRadioButton.Checked := True;
    GoldSpinEdit.Value := Params.Integers[1];
    GoldOperatorComboBox.ItemIndex := Params.Integers[2];
  end;

  procedure InitPossessionCondition(ARadio: TRadioButton; AComboBox: TComboBox;
    ACheckBox: TCheckBox);
  begin
    CondPageControl.PageIndex := 3;
    ARadio.Checked := True;
    AComboBox.ItemIndex := Params.Integers[1] - 1;
    if ACheckBox <> nil then begin
      if Params[2].JSONType = jtBoolean then
        ACheckBox.Checked := Params.Booleans[2]
      else if Params[2].JSONType = jtNumber then
        ACheckBox.Checked := Params.Integers[2] <> 0
    end;
  end;

  procedure InitKeyCondition;
  var
    I: Integer;
  begin
    CondPageControl.PageIndex := 3;
    KeyRadioButton.Checked := True;

    for I := Low(KeyCodes) to High(KeyCodes) do
      if Params.Strings[1] = KeyCodes[I] then
        KeyComboBox.ItemIndex := I;
  end;

  procedure InitCodeCondition;
  begin
    CondPageControl.PageIndex := 3;
    CodeRadioButton.Checked := True;
    CodeEdit.Text := Params.Strings[1];
  end;

begin
  InitialSetUp;
  Params := GetFirstParams;

  case Params.Integers[0] of
    0: InitSwitchCondition;
    1: InitVariableCondition;
    2: InitSelfSwitchCondition;
    3: InitTimerCondition;
    4: InitActorCondition;
    5: InitEnemyCondition;
    6: InitMapObjectCondition;
    7: InitGoldCondition;
    8: InitPossessionCondition(ItemRadioButton, ItemComboBox, nil);
    9: InitPossessionCondition(WeaponRadioButton, WeaponComboBox, WeaponIncludeEquipmentCheckBox);
    10: InitPossessionCondition(ArmourRadioButton, ArmourComboBox, ArmourIncludeEquipmentCheckBox);
    11: InitKeyCondition;
    12: InitCodeCondition;
    13: InitVehicleCondition;
  end;

  ElseCheckBox.Checked :=
    FindStartOfSubcommands(CONDITIONAL_BRANCH_ELSE_EC_CODE) > -1;
end;

procedure TECCondBranchFrame.MakeResultingCommand;
begin
  ResultingCommand := TJSONArray.Create;
  ResultingCommand.Add(TJSONObject.Create([
    'code', CONDITIONAL_BRANCH_IF_EC_CODE,
    'indent', Indent,
    'parameters', MakeCondition
  ]));
  AddExitingSubCommands(ResultingCommand, CONDITIONAL_BRANCH_IF_EC_CODE);
  if ElseCheckBox.Checked then begin
      ResultingCommand.Add(TJSONObject.Create([
        'code', CONDITIONAL_BRANCH_ELSE_EC_CODE,
        'indent', Indent,
        'parameters', MakeCondition
      ]));
      AddExitingSubCommands(ResultingCommand, CONDITIONAL_BRANCH_ELSE_EC_CODE);
  end;
  ResultingCommand.Add(TJSONObject.Create([
    'code', CONDITIONAL_BRANCH_END_EC_CODE,
    'indent', Indent,
    'parameters', TJSONArray.Create([])
  ]));
end;

function TECCondBranchFrame.FindStartOfSubcommands(Index: Integer): Integer;
var
  Code: Integer;
  AIndent: Integer;
begin
  Result := -1;

  if Index = CONDITIONAL_BRANCH_IF_EC_CODE then
    Result := ListIndex
  else if Index = CONDITIONAL_BRANCH_ELSE_EC_CODE then begin
    if (EcList = nil) or (EcList.JSONType <> jtArray) then
      Exit;

    Result := ListIndex + 1;
    while Result < EcList.Count do begin
      Code := EcList.Objects[Result].Integers['code'];
      AIndent := EcList.Objects[Result].Integers['indent'];
      if (Code = CONDITIONAL_BRANCH_ELSE_EC_CODE) and (AIndent = Indent) then
        Break;

      if (Code = CONDITIONAL_BRANCH_END_EC_CODE) and (AIndent = Indent) then
      begin
        Result := -1;
        Break
      end;

      Inc(Result)
    end
  end;
end;

end.

